module.exports = app => {
    const express = require('express')
    const router = express.Router({
        mergeParams: true //合并resource参数
    }) //子路由

    //引用校验token
    const jwt = require('jsonwebtoken')

    const Category = require('../../models/Category')
    const Article = require('../../models/Article')
    const Hero = require('../../models/Hero')
    const AdminUser = require('../../models/AdminUser')
    const Item = require('../../models/Item')
    const Ad = require('../../models/Ad')

    //调用assert来返回错误
    const assert = require('http-assert')

    // 创建数据
    router.post('/', async (request, response) => {
        const model = await request.Model.create(request.body)
        response.send(model)
    });

    // 获取资源列表,populate('parent')是可以取出关联字段的IPA,.limit()是取出最大数目
    router.get('/', async (request, response) => {

        let items = await request.Model.find().populate('parent').limit(1000)

        if (request.Model == Hero) {
            items = await request.Model.find().populate('items1').lean()
        }

        response.send(items)
    });

    // 保存编辑更新
    router.put('/:id', async (request, response) => {
        const model = await request.Model.findByIdAndUpdate(request.params.id, request.body)
        response.send(model)
    });

    // 获取编辑分类的具体内容
    router.get('/:id', async (request, response) => {
        const model = await request.Model.findById(request.params.id, response.body)
        response.send(model)
    })

    // 删除接口
    router.delete('/:id', async (request, response) => {
        const model = await request.Model.findByIdAndDelete(request.params.id)
        response.send({
            success: true
        })
    });

    // 登陆校验校验中间件的
    const authMiddleware = async (request, response, next) => {

        const token = String(request.headers.authorization || '').split(' ').pop()
        assert(token, 401, '请先登陆')

        const {
            id
        } = jwt.verify(token, app.get('secret'))
        assert(token, 401, '请先登陆')

        //挂载到req表示请求的是谁
        request.user = await AdminUser.findById(id)
        assert(request.user, 401, '请先登陆')

        next()
    }

    //获取文件的验证
    const resourceMiddleware = async (request, response, next) => {
        // 这里是中间件处理动态路由,封住了请求方法,用过request.Model来使用请求的名称
        const modelName = require('inflection').classify(request.params.resource)
        request.Model = require(`../../models/${modelName}`)
        next()
    }

    //统一路由的封装
    app.use('/admin/api/rest/:resource', authMiddleware, resourceMiddleware, router)

    // 图片处理,upload.single('file')上传单个文件
    const multer = require("multer")
    const upload = multer({
        dest: __dirname + '/../../uploads'
    })
    app.post('/admin/api/upload', upload.single('file'), async (request, response) => {
        const file = request.file
        file.url = `http://localhost:3000/uploads/${file.filename}`
        response.send(file)
    })

    // 登陆路由
    app.post('/admin/api/login', async (request, response) => {
        const {
            username,
            password
        } = request.body
        // 1、根据用户名找用户
        // const AdminUser= require('../../models/AdminUser')
        const user = await AdminUser.findOne({
            username: username
        }).select('+password') //数据库设置了不可读取，需要使用+号

        assert(user, 422, '用户不存在')

        // 2、bcrypt校验密码,compareSync(明文, 密文)
        const isValid = require('bcrypt').compareSync(password, user.password)

        assert(isValid, 422, '密码错误')

        // 返回token
        // const jwt = require('jsonwebtoken')

        // 3、加密返回,get会和路由冲突，通过参数的数量让路由进行判断
        const token = jwt.sign({
            id: user._id,
        }, app.get('secret'))

        response.send({
            token: token
        })
    })

    //错误处理4个参数
    app.use(async (err, request, response, next) => {
        response.status(err.statusCode || 500).send({
            message: err.message
        })
    })

    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口
    //处理客户端接口


    router.get('/news/list', async (req, response) => {

        const parent = await Category.findOne({
            name: "新闻分类"
        })

        //使用聚合查询aggregate
        const cats = await Category.aggregate([{
                $match: {
                    //过滤数据
                    parent: parent._id
                }
            },
            {
                $lookup: {
                    //集合名字
                    from: 'articles',
                    localField: '_id',
                    foreignField: 'categories',
                    as: 'newsList'
                }
            },
            {
                $addFields: {
                    //修改取出的字段，取出个5字段
                    newsList: {
                        $slice: ['$newsList', 5]
                    }
                }
            }
        ])

        const subCats = cats.map(v => v._id)
        cats.unshift({
            name: '热门',
            newsList: await Article.find().where({
                categories: {
                    $in: subCats
                }
                //lean()是为了转为存粹的json对象
            }).populate('categories').limit(5).lean()
        })

        cats.map(cat => {
            cat.newsList.map(news => {
                //一个文章有多个分类
                //如果是热门，那么要显示原来的分类，如果不是那么就统一改成当前的分类
                news.categoryName = cat.name === '热门' ?
                    news.categories[0].name : cat.name
                return news
            })
            return cat
        })
        response.send(cats)
    })


    //英雄列表接口
    router.get('/heroes/list', async (req, response) => {

        const parent = await Category.findOne({
            name: "英雄分类"
        })

        //使用聚合查询
        const cats = await Category.aggregate([{
                $match: {
                    //过滤数据
                    parent: parent._id
                }
            },
            {
                $lookup: {
                    //集合名字
                    from: 'heroes',
                    localField: '_id',
                    foreignField: 'categories',
                    as: 'heroList'
                }
            },
        ])

        const subCats = cats.map(v => v._id)
        cats.unshift({
            name: '热门',
            heroList: await Hero.find().where({
                categories: {
                    $in: subCats
                }
                //只取10个
            }).limit(10).lean()
        })
        response.send(cats)
    })


    //文章详情
    router.get('/articles/:id', async (request, response) => {
        const data = await Article.findById(request.params.id).lean()
        data.related = await Article.find().where({
            categories: {
                $in: data.categories
            }
        }).limit(2)
        response.send(data)
    })


    //英雄详情
    router.get('/heroes/:id', async (request, response) => {
        const data = await Hero
            .findById(request.params.id)
            .populate('categories items1 items2 partners.hero')
            .lean()
        response.send(data)
    })


    app.use('/web/api', router)
}